//
// Created by denglibin on 19-5-9.
//

#ifndef OPENGL_CAMERA_H
#define OPENGL_CAMERA_H

#include "settings.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/**
 * 摄像机类
 */
class Camera {
private:
    glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); //目标方向
    glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f); //上向量
    float speedFactor = 2.5f; //摄像机移动速度因子

    //控制摄像机方向的一些变量
    float lastX = SCR_WIDTH/2, lastY = SCR_HEIGHT/2; //上一帧的鼠标位置 初始值设置为屏幕的中心（屏幕的尺寸是800x600）
    float pitch = 0; //方向向量与x,z平面的夹角(由y坐标控制 鼠标上下移动) 默认是0度, 因为默认方向是向z负方向
    float yaw = 90; //方向向量在x,z平面上的投影与x轴的夹角(由x坐标控制 鼠标左右移动,与z轴的夹角则为:90度-yaw)  默认90度 因为默认方向是向z负方向
    bool firstMouse = true;
    float sensitivity = 0.05f;//方向旋转灵敏度
public:
    glm::vec3 cameraPos   = glm::vec3(0.0f, 0.0f,  5.0f); //摄像机位置
    /**
     * 构造函数
     */
    Camera();

    /**
     * 目标方向前进
     * @param deltaTime 当前帧与上一帧的时间差 如果deltaTime很大，就意味着上一帧的渲染花费了更多时间，所以这一帧的速度需要变得更高来平衡渲染所花去的时间
     */
    void moveFront(float deltaTime);
    /**
     * 目标方向后退
     * @param deltaTime 当前帧与上一帧的时间差
     */
    void moveBack(float deltaTime);
    /**
     * 左移
     * @param deltaTime 当前帧与上一帧的时间差
     */
    void moveLeft(float deltaTime);
    /**
     * 右移
     * @param deltaTime 当前帧与上一帧的时间差
     */
    void moveRight(float deltaTime);

    /**
     * 上移
     * @param deltaTime
     */
    void moveUp(float deltaTime);
    /**
     * 下移
     * @param deltaTime
     */
    void moveDown(float deltaTime);

    /**
     * 鼠标移动 改变摄像机方向 鼠标左移摄像机左转,鼠标右移摄像机右转,鼠标上移摄像机向上看,鼠标下移摄像机往下看
     * @param xPos 鼠标x坐标
     * @param yPos 鼠标y坐标
     */
    void updateFront(double xPos, double yPos);

    /**
     * 获取观察矩阵
     * @return
     */
    glm::mat4 getViewMatrix();


};


#endif //OPENGL_CAMERA_H
